package com.ganhuoshitang.限流算法;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.*;

/**
 * 1、计数器算法
 * 计数器采用简单的计数操作，到一段时间节点后自动清零
 * 比较糙的写法
 * 优缺点 实现起来非常简单。 控制力度太过于简略，假如1s内限制3次，那么如果3次在前100ms内已经用完，后面的900ms将只能处于阻 塞状态，白白浪费掉。
 */
public class Counter {

    public static void main(String[] args) {
        //计数器，这里用信号量实现
        final Semaphore semaphore = new Semaphore(3);
        //定时器，到点清零
        ScheduledExecutorService service = Executors.newScheduledThreadPool(1);

        //3000 是等3秒之后开启定时任务  2000 是每隔2秒之后开始执行任务
        service.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                //每隔3秒释放信号量
                semaphore.release(1);
            }
        }, 3000, 2000, TimeUnit.MILLISECONDS);

        //模拟无数个请求从天而降
        int i = 0 ;
        while (true) {
            i ++;
            try {
                //判断计数器  线程到这回阻塞
                semaphore.acquire();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            // 如果准许响应，打印一个ok
            System.out.println(getNowTime() + ": 第" + i + "个请求");
        }
    }

    public static String getNowTime(){
        Date d = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
//        System.out.println("当前时间：" + sdf.format(d));
        return sdf.format(d);
    }
}